package com.misboot.document.utils.wps;

import com.misboot.document.config.ReqKeys;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import static org.apache.commons.codec.binary.Base64.encodeBase64String;

public class SignatureUtil {
    public static String getKeyValueStr(Map<String, String> params) {
        List<String> keys = new ArrayList<String>() {
            {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    add(entry.getKey());
                }
            }
        };
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            String value = params.get(key) + "&";
            sb.append(key).append("=").append(value);

            //sb.append(URLEncoder.encode(key, "utf-8")).append('=').append(URLEncoder.encode(value, "utf-8"));

        }
        return sb.toString();
    }

    public static String getSignature(Map<String, String> params, String appSecret) {
        List<String> keys = new ArrayList<String>() {
            {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    add(entry.getKey());
                }
            }
        };

        // 将所有参数按key的升序排序
        keys.sort(String::compareTo);

        // 构造签名的源字符串
        StringBuilder contents = new StringBuilder();
        for (String key : keys) {
            if (key.equals(ReqKeys.SIGNATURE_KEY)) {
                continue;
            }
            contents.append(key).append("=").append(params.get(key));
        }
        contents.append(ReqKeys.SECRET_KEY).append("=").append(appSecret);

        // 进行hmac sha1 签名
        //byte[] bytes = HmacUtils.hmacSha1(appSecret.getBytes(), contents.toString().getBytes());
        byte[] bytes= hmacSha1(appSecret.getBytes(),contents.toString().getBytes());


        //字符串经过Base64编码
        String sign = encodeBase64String(bytes);
        try {
            return URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Map<String, String> paramToMap(String paramStr) {
        String[] params = paramStr.split("&");
        return new HashMap<String, String>() {
            {
                for (String param1 : params) {
                    String[] param = param1.split("=");
                    if (param.length >= 2) {
                        String key = param[0];
                        StringBuilder value = new StringBuilder(param[1]);
                        for (int j = 2; j < param.length; j++) {
                            value.append("=").append(param[j]);
                        }
                        put(key, value.toString());
                    }
                }
            }
        };
    }

    /**
     * 生成签名
     *
     * @param action     GET、POST
     * @param url        调用接口的url，转换接口时传入接口地址不带参；查询接口时地址带参数
     * @param contentMd5 通过getMD5方法计算的值
     * @param headerDate 通过getGMTDate方法计算的值
     */
    private static String getSignature(String action, String url, String contentMd5, String headerDate, String convertAppsecret) {
        try {
            URL ur = new URL(url);
            String key = ur.getPath();
            if (!StringUtils.isEmpty(ur.getQuery())) {
                key = key + "?" + ur.getQuery();
            }
            String signStr = action + "\n" + contentMd5 + "\n" + Common.CONTENTTYPE + "\n" + headerDate + "\n" + key;
            // 进行hmac sha1 签名
            //byte[] bytes = HmacUtils.hmacSha1(convertAppsecret.getBytes(), signStr.getBytes());
            byte[] bytes= hmacSha1(signStr.getBytes(),convertAppsecret.toString().getBytes());

            return encodeBase64String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String getAuthorization(String action, String url, String contentMd5, String headerDate, String appid, String convertAppsecret) {
        return "WPS " + appid + ":" + getSignature(action, url, contentMd5, headerDate, convertAppsecret); //签名
    }


    private static String getUrlParam(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (builder.length() > 0) {
                builder.append('&');
            }
            builder.append(URLEncoder.encode(entry.getKey(), "utf-8")).append('=').append(URLEncoder.encode(entry.getValue(), "utf-8"));
        }
        return  builder.toString();
    }

    private static String getSignature1(Map<String, String> params, String appSecret) {
        List<String> keys=new ArrayList();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            keys.add(entry.getKey());
        }

        // 将所有参数按key的升序排序
        Collections.sort(keys, new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });

        // 构造签名的源字符串
        StringBuilder contents=new StringBuilder("");
        for (String key : keys) {
            if (key=="_w_signature"){
                continue;
            }
            contents.append(key+"=").append(params.get(key));
            System.out.println("key:"+key+",value:"+params.get(key));
        }
        contents.append("_w_secretkey=").append(appSecret);

        // 进行hmac sha1 签名
        byte[] bytes= hmacSha1(appSecret.getBytes(),contents.toString().getBytes());
        //字符串经过Base64编码
        String sign= encodeBase64String(bytes);
        try {
            sign = URLEncoder.encode( sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(sign);
        return sign;
    }

    public static byte[] hmacSha1(byte[] key, byte[] data) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
            Mac mac = Mac.getInstance(signingKey.getAlgorithm());
            mac.init(signingKey);
            return mac.doFinal(data);
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

}
